// ++++++++++++++++++++++++++++++++++++++++
// 《零基础Go语言算法实战》源码
// ++++++++++++++++++++++++++++++++++++++++
// Author:廖显东（ShirDon）
// Blog:https://www.shirdon.com/
// Gitee:https://gitee.com/shirdonl/goAlgorithms.git
// Buy link :https://item.jd.com/14101229.html
// ++++++++++++++++++++++++++++++++++++++++

package main

import (
	"fmt"
	"math/rand"
)

type Node struct {
	data interface{} // 数据字段来保存节点的数据
	next *Node       // 指向列表中下一个节点的指针
}

type List struct {
	head *Node // 指向列表中第一个节点的指针
}

func (l *List) AddNode(d interface{}) {
	// 使用给定的数据创建一个新节点
	list := &Node{data: d, next: nil}

	// 如果列表为空，则将新节点设置为头
	if l.head == nil {
		l.head = list
	} else { // 否则，找到最后一个节点并将新节点添加到末尾
		p := l.head
		for p.next != nil {
			p = p.next
		}
		p.next = list
	}
}

func ConvertSinglyToCircular(l *List) {
	// 查找列表中的最后一个节点
	p := l.head
	for p.next != nil {
		p = p.next
	}

	// 改变最后一个节点的下一个指针指向头节点，
	// 使链表循环
	p.next = l.head
}

func PrintCircular(l *List) {
	p := l.head
	for {
		// 打印当前节点的数据
		fmt.Printf("-> %v ", p.data)

		// 如果下一个节点是头节点，我们就绕了一整圈
		if p.next == l.head {
			break
		}

		// 否则，移动到列表中的下一个节点
		p = p.next
	}
}

func main() {
	list := List{}
	for i := 0; i < 3; i++ {
		list.AddNode(rand.Intn(99))
	}
	ConvertSinglyToCircular(&list)
	PrintCircular(&list)
}

//$ go run linkList3.go
//-> 23 -> 78 -> 20
